home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
TECHNICA
/
COMPUTER
/
H254.ZIP
/
IRITSM3S.ZIP
/
POLY3D-R
/
PREPDATA.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-10
|
6KB
|
180 lines
/*****************************************************************************
* Routines to prepare objects for the scan conversion: *
* At this stage, it is assumed all vertices normals has been evaluated, if *
* is is required to interpolate them (i.e. Gouraud shading.) *
* This module sort the polygons into hash table of GlblShadeInfo.ScrnYSize size, *
* according to their lowest vertex, and update a pointer to it. *
* *
* Written by: Gershon Elber Ver 2.0, Mar. 1990 *
*****************************************************************************/
#ifdef __MSDOS__
#include <stdlib.h>
#endif /* __MSDOS__ */
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "program.h"
#include "genmat.h"
#include "iritprsr.h"
static void PrepareAllObjects(IPObjectStruct *PObjects);
static void PrepareOneObject(IPObjectStruct *PObject);
static void PrepareOnePolygon(IPPolygonStruct *PPolygon);
static int UpdateBBoxPolygon(IPPolygonStruct *PPolygon);
static void UpdateScanConvertData(int MinVertex, IPPolygonStruct *PPolygon);
/*****************************************************************************
* Routine to prepare NumOfObjects given in Objects from FileDescription FD *
* according to view matrix Mat. If NumOfObjects == 0 then all the objects *
* defined by the data sturcture are handled, and NumOfObjects is set to real *
* number of objects exists. *
*****************************************************************************/
void PrepareViewData(IPObjectStruct *PObjects)
{
long
SaveTime = time(NULL);
fprintf(stderr, "\nPass 2, Polys = ");
PrepareAllObjects(PObjects);
fprintf(stderr, ", %ld seconds.", time(NULL) - SaveTime);
}
/*****************************************************************************
* Scan all objects. *
*****************************************************************************/
static void PrepareAllObjects(IPObjectStruct *PObjects)
{
while (PObjects) {
PrepareOneObject(PObjects);
PObjects = PObjects -> Pnext;
}
}
/*****************************************************************************
* Routine to prepare one object PObject. *
*****************************************************************************/
static void PrepareOneObject(IPObjectStruct *PObject)
{
struct IPPolygonStruct *PList = PObject -> U.PPolygon;
while (PList) {
PrepareOnePolygon(PList);
PList = PList -> Pnext;
}
}
/*****************************************************************************
* Routine to prepare one polygon PPolygon. *
*****************************************************************************/
static void PrepareOnePolygon(IPPolygonStruct *PPolygon)
{
static int
PolyCount = 0;
int i;
RealType CpCoord[3];
IPVertexStruct
*VList = PPolygon -> PVertex;
fprintf(stderr, "\b\b\b\b\b%5d", ++PolyCount);
GlblNumOfPolys++;
for (; VList != NULL; VList = VList -> Pnext) {
/* Convert the coordinate to screen space (pres.). */
MultVecby4by4(CpCoord, VList -> Coord, GlblViewMat);
for (i = 0; i < 3; i++) VList -> Coord[i] = CpCoord[i];
}
if (PPolygon -> Type != IP_POLYGON) return;
/* Find X, Y extremum in screen space, and use the lowest vertex in Y to */
/* initialize the scan conversion structure of the polygon: */
i = UpdateBBoxPolygon(PPolygon);
UpdateScanConvertData(i, PPolygon);
/* Transform the polygon plane equation as well, and normalize it: */
UpdateEqnPolygon(PPolygon, FALSE);
}
/*****************************************************************************
* Routine to update polygon boundary box in screen space: *
* Note this routine is called after the polygons was checked for validity - *
* all the list of objects was found to be vertices only. *
*****************************************************************************/
static int UpdateBBoxPolygon(IPPolygonStruct *PPolygon)
{
int i,
MinV = 0;
RealType *Coord, Xmin, Xmax, Ymin, Ymax;
struct IPVertexStruct
*VList = PPolygon -> PVertex;
Xmin = Xmax = VList -> Coord[0];
Ymin = Ymax = VList -> Coord[1];
for (VList = VList -> Pnext, i = 1;
VList != NULL;
VList = VList -> Pnext, i++) {
Coord = VList -> Coord;
if (Coord[0] > Xmax) Xmax = Coord[0];
if (Coord[0] < Xmin) Xmin = Coord[0];
if (Coord[1] > Ymax) Ymax = Coord[1];
if (Coord[1] < Ymin) {
Ymin = Coord[1];
MinV = i;
}
}
PPolygon -> Xmin = (int) Xmin;
PPolygon -> Xmax = (int) Xmax;
PPolygon -> Ymin = (int) Ymin;
PPolygon -> Ymax = (int) Ymax;
return MinV;
}
/*****************************************************************************
* Routine to update polygon scan conversion information: *
* Each polygon (Remember they must be convex), has two boundaries we cross *
* by the scan lines if it is active. These are LeftBndry and RightBndry we *
* update here. *
*****************************************************************************/
static void UpdateScanConvertData(int MinVertex, IPPolygonStruct *PPolygon)
{
int i;
struct IPVertexStruct *VMinY, *VBefore, *VAfter,
*VList = PPolygon -> PVertex;
struct PolygonScanConvertStruct *PScan;
/* Find the minimum location again: */
if (MinVertex == 0) {
/* Its the first vertex that has minimum Y value: */
VMinY = VList;
for (VBefore = VList;
VBefore -> Pnext != NULL;
VBefore = VBefore -> Pnext);
VAfter = VList -> Pnext;
}
else {
for (i = 1, VBefore = VList;
i < MinVertex;
i++, VBefore = VBefore -> Pnext);
VMinY = VBefore -> Pnext;
VAfter = VMinY -> Pnext ? VMinY -> Pnext : VList;
}
PPolygon -> PAux = MyMalloc(sizeof(struct PolygonScanConvertStruct));
PScan = (PolygonScanConvertStruct *) PPolygon -> PAux;
PScan -> Bndry1.VMinY = VMinY;
PScan -> Bndry1.VMaxY = VBefore;
PScan -> Bndry1.MaxEdgeY = (int) VBefore -> Coord[1];
PScan -> Bndry2.VMinY = VMinY;
PScan -> Bndry2.VMaxY = VAfter;
PScan -> Bndry2.MaxEdgeY = (int) VAfter -> Coord[1];
}